package com.cloudlinkscm.base.authcenter.config;

import com.cloudlinkscm.base.authcenter.dao.UserAccountDao;
import com.cloudlinkscm.base.authcenter.shiro.CustomRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.credential.*;
import org.apache.shiro.crypto.hash.DefaultHashService;
import org.apache.shiro.crypto.hash.HashService;
import org.apache.shiro.crypto.hash.format.HashFormat;
import org.apache.shiro.crypto.hash.format.HexFormat;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author : tac
 * @date : 28/07/2017
 */
@Configuration
public class ShiroConfiguration {

    public static final String HASH_ALGORITHM_NAME = "MD5";
    public static final int HASH_ITERATIONS = 5;

    @Bean
    public SecurityManager securityManager(Realm realm) {
        DefaultSecurityManager bean = new DefaultSecurityManager();
        bean.setRealm(realm);
        SecurityUtils.setSecurityManager(bean);
        return bean;
    }

    @Bean
    public Realm customerRealm(UserAccountDao dao, CredentialsMatcher credentialsMatcher) {
        CustomRealm bean = new CustomRealm();
        bean.setUserAccountDao(dao);
        bean.setCredentialsMatcher(credentialsMatcher);
        return bean;
    }

    @Bean
    public PasswordService passwordService(HashService hashService, HashFormat hashFormat){
        return new PasswordService() {
            private DefaultPasswordService delegateService = new DefaultPasswordService();
            {
                delegateService.setHashService(hashService);
                delegateService.setHashFormat(hashFormat);
            }

            @Override
            public String encryptPassword(Object plaintextPassword) throws IllegalArgumentException {
                return delegateService.encryptPassword(plaintextPassword);
            }

            @Override
            public boolean passwordsMatch(Object submittedPlaintext, String encrypted) {
                return delegateService.passwordsMatch(submittedPlaintext, encrypted);
            }
        };
    }

    @Bean
    public HashService hashService(){
        DefaultHashService bean = new DefaultHashService();
        bean.setHashAlgorithmName(HASH_ALGORITHM_NAME);
        bean.setHashIterations(HASH_ITERATIONS);
        bean.setGeneratePublicSalt(false);
        return bean;
    }

    @Bean
    public CredentialsMatcher credentialsMatcher(PasswordService passwordService){
        PasswordMatcher bean = new PasswordMatcher();
        bean.setPasswordService(passwordService);
        return bean;
    }

    @Bean
    public HashFormat hashFormat(){
        return new HexFormat();
    }
}
